package cn.rubintry.calculator

import android.widget.TextView
import java.math.BigDecimal


/**
 * 高精度浮点计算器
 */
class BigDecimalCalculator() : BaseCalculator<BigDecimal>() , ICalculator<BigDecimal> {

    override fun forcePositive(): BigDecimalCalculator {
        forcePositive = true
        return this
    }

    override fun add(other: Any?): BigDecimalCalculator {
        checkResultNotNull()
        when(other){
            is BigDecimalModule -> {
                resultModule?.add(other)
            }

            is TextView -> {
                resultModule?.add(BigDecimalModule(other))
            }

            is String? -> {
                resultModule?.add(BigDecimalModule(other ?: "0"))
            }

            is Int -> {
                resultModule?.add(BigDecimalModule(other.toString()))
            }

            is Double -> {
                resultModule?.add(BigDecimalModule(other.toString()))
            }

            is BigDecimal -> {
                resultModule?.add(BigDecimalModule(other.toInt().toString()))
            }
        }

        return this
    }

    override fun subtract(other: Any?): BigDecimalCalculator {
        checkResultNotNull()
        when(other){
            is BigDecimalModule -> {
                resultModule?.subtract(other)
            }

            is TextView -> {
                resultModule?.subtract(BigDecimalModule(other))
            }

            is String? -> {
                resultModule?.subtract(BigDecimalModule(other ?: "0"))
            }

            is Int -> {
                resultModule?.subtract(BigDecimalModule(other.toString()))
            }

            is Double -> {
                resultModule?.subtract(BigDecimalModule(other.toString()))
            }

            is BigDecimal -> {
                resultModule?.subtract(BigDecimalModule(other.toInt().toString()))
            }
        }
        return this
    }


    override fun multiply(other: Any?, scale: Int): BigDecimalCalculator {
        checkResultNotNull()
        when(other){
            is BigDecimalModule -> {
                resultModule?.multiply(other , scale)
            }

            is TextView -> {
                resultModule?.multiply(BigDecimalModule(other))
            }

            is String? -> {
                resultModule?.multiply(BigDecimalModule(other ?: "0") , scale)
            }

            is Int -> {
                resultModule?.multiply(BigDecimalModule(other.toString()) , scale)
            }

            is Double -> {
                resultModule?.multiply(BigDecimalModule(other.toString()) , scale)
            }

            is BigDecimal -> {
                resultModule?.multiply(BigDecimalModule(other.toInt().toString()) , scale)
            }
        }
        return this
    }


    override fun divide(other: Any?, scale: Int): BigDecimalCalculator {
        checkResultNotNull()
        when(other){
            is BigDecimalModule -> {
                resultModule?.divide(other , scale)
            }

            is TextView -> {
                resultModule?.divide(BigDecimalModule(other) , scale)
            }

            is String? -> {
                resultModule?.divide(BigDecimalModule(other ?: "0") , scale)
            }

            is Int -> {
                resultModule?.divide(BigDecimalModule(other.toString()) , scale)
            }

            is Double -> {
                resultModule?.divide(BigDecimalModule(other.toString()) , scale)
            }

            is BigDecimal -> {
                resultModule?.divide(BigDecimalModule(other.toInt().toString()) , scale)
            }
        }
        return this
    }

    override fun appendUnit(unit: String): BigDecimalCalculator {
        checkResultNotNull()
        resultModule?.appendUnit(unit)
        return this
    }

    override fun into(vararg target: TextView?) {
        assert(resultModule != null){"请先调用加减乘除方法"}
        for (textView in target) {
            textView?.text = resultModule?.getNumberFromView()
        }
    }

    override fun toString(): String {
        return resultModule.toString()
    }

    override fun copy(): BigDecimalCalculator {
        val instance = BigDecimalCalculator::class.java.newInstance()
        copyFields(this.javaClass , instance)
        return instance
    }

    private fun copyFields(clazz: Class<*>?, instance: BigDecimalCalculator) {
        val declaredFields = clazz?.declaredFields
        declaredFields?.let {
            for (declaredField in it) {
                declaredField.isAccessible = true
                declaredField.set(instance , declaredField.get(this))
            }
        }

        if(null != clazz?.superclass){
            copyFields(clazz.superclass , instance)
        }
    }
}